package web

import (
	"gitee.com/tools/internal/service"
	"gitee.com/tools/internal/web/tools/common"
	"github.com/gin-gonic/gin"
	uuid "github.com/lithammer/shortuuid/v4"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
)

type Format struct {
	svc *service.FormatService
}

func NewFormat(svc *service.FormatService) *Format {
	return &Format{
		svc: svc,
	}
}
func (f *Format) Router(r *gin.Engine) {
	// 限制文件上传的最大容量
	r.MaxMultipartMemory = 1024 * 1024 * 512
	g := r.Group("/format")
	g.GET("/pdftoword", f.pdfToword)
	g.GET("/pdfToimage", f.pdfToPng)
	g.GET("/pdfToExcel", f.pdfToExcel)
	g.GET("/imagetoword", f.imageToWord)
	g.GET("/imagetoExcel", f.imageToExcel)
	g.GET("/imagetopdf", f.imageToPdf)
	g.POST("/upload", Upload)
}
func (f *Format) saveFile(ctx *gin.Context) string {
	var filename string
	file, header, err := ctx.Request.FormFile("format")

	defer file.Close()
	if err != nil {
		ctx.AbortWithStatusJSON(http.StatusOK, common.Result{
			Code:    common.ErrorUserInputInvalid,
			Message: "参数无效",
			Data:    nil,
		})
		return filename
	}
	id := uuid.New()
	filename = id + header.Filename
	err = ctx.SaveUploadedFile(header, filename)
	if err != nil {
		log.Println("保存文件失败")
		ctx.AbortWithStatusJSON(http.StatusOK, common.Result{
			Code:    common.ErrFileSave,
			Message: "系统错误",
			Data:    nil,
		})
		return filename
	}
	return filename
}

func (f *Format) saveImage(ctx *gin.Context) []string {
	//r.MultipartForm.File["images"]
	err := ctx.Request.ParseMultipartForm(10 << 20)
	if err != nil {
		return nil
	}
	form := ctx.Request.MultipartForm
	imagePath := make([]string, 0)
	//file, err := ctx.MultipartForm()
	//if err != nil {
	//	return
	//}
	for _, filehaders := range form.File {
		for _, fileheader := range filehaders {
			file, err := fileheader.Open()
			if err != nil {
				ctx.AbortWithStatusJSON(http.StatusOK, common.Result{
					Code:    common.ErrSystem,
					Message: "系统错误",
					Data:    nil,
				})
			}
			defer file.Close()

			// 创建一下本地文件， 保存上传的图片
			id := uuid.New()
			filename := id + fileheader.Filename
			// 创建保存文件的目录
			pwd, err := os.Getwd()
			uploadDir := filepath.Join(pwd, "upload/images")
			err = os.MkdirAll(uploadDir, os.ModePerm)
			if err != nil {
				log.Println("无法创建保存文件的目录")
				ctx.AbortWithStatusJSON(http.StatusOK, common.Result{
					Code:    common.ErrSystemCreateFile,
					Message: "系统错误",
					Data:    nil,
				})
				return nil
			}
			// 保存文件路径
			savePath := filepath.Join(uploadDir, filename)
			out, err := os.Create(savePath)
			if err != nil {
				log.Println("无法创建保存文件的目录")
				ctx.JSON(http.StatusOK, common.Result{
					Code:    common.ErrSystemCreateFile,
					Message: "系统错误",
					Data:    nil,
				})
				return nil
			}
			defer out.Close()

			_, err = io.Copy(out, file)
			if err != nil {
				log.Println("拷贝文件内容失败")
				ctx.JSON(http.StatusOK, common.Result{
					Code:    common.ErrSystemFileCopy,
					Message: "系统错误",
					Data:    nil,
				})
				return nil
			}
			imagePath = append(imagePath, savePath)
		}
	}

	return imagePath
}

func (f *Format) pdfToword(ctx *gin.Context) {
	filename := f.saveFile(ctx)
	res, err := f.svc.PdfToWordReq(filename)
	if err != nil {
		log.Println(res.Message)
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}

	result, err := f.svc.GetConvertResult(res.Id)
	if err != nil || !result.Completed || result.Status == "Fail" {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}

	if result.Status == "DocProcessing" {
		// 重试
	}

	ctx.JSON(http.StatusOK, common.Result{
		Code:    0,
		Message: "转换成功",
		Data:    result.Data,
	})
	return
}

func (f *Format) pdfToPng(ctx *gin.Context) {
	filename := f.saveFile(ctx)
	res, err := f.svc.PdfToImage(filename)
	if err != nil {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}

	result, err := f.svc.GetConvertResult(res.Id)
	if err != nil {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, common.Result{
		Code:    0,
		Message: "转换成功",
		Data:    result.Data,
	})
	return
}

func (f *Format) pdfToExcel(ctx *gin.Context) {
	filename := f.saveFile(ctx)
	res, err := f.svc.PdfToImage(filename)
	if err != nil {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}

	result, err := f.svc.GetConvertResult(res.Id)
	if err != nil {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, common.Result{
		Code:    0,
		Message: "转换成功",
		Data:    result.Data,
	})
	err = os.Remove(filename)
	if err != nil {
		log.Println("删除文件失败")
		// 重试
	}
	return
}

func (f *Format) imageToWord(ctx *gin.Context) {
	filenames := f.saveImage(ctx)
	res, err := f.svc.ImageToWord("png", filenames...)
	if err != nil {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}

	result, err := f.svc.GetConvertResult(res.Id)
	if err != nil {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, common.Result{
		Code:    0,
		Message: "转换成功",
		Data:    result.Data,
	})
	for _, filename := range filenames {
		err = os.Remove(filename)
		if err != nil {
			log.Println("删除文件失败")
			// 重试
		}
	}
	return
}

func (f *Format) imageToExcel(ctx *gin.Context) {
	filenames := f.saveImage(ctx)
	res, err := f.svc.ImageToExcel("png", filenames...)
	if err != nil {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}

	result, err := f.svc.GetConvertResult(res.Id)
	if err != nil {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, common.Result{
		Code:    0,
		Message: "转换成功",
		Data:    result.Data,
	})
	for _, filename := range filenames {
		err = os.Remove(filename)
		if err != nil {
			log.Println("删除文件失败")
			// 重试
		}
	}
	return
}

func (f *Format) imageToPdf(ctx *gin.Context) {
	filenames := f.saveImage(ctx)
	res, err := f.svc.ImageToPdf("png", filenames...)
	if err != nil {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}

	result, err := f.svc.GetConvertResult(res.Id)
	if err != nil {
		ctx.JSON(http.StatusOK, common.Result{
			Code:    common.ErrSystem,
			Message: "转换失败",
			Data:    nil,
		})
		return
	}
	ctx.JSON(http.StatusOK, common.Result{
		Code:    0,
		Message: "转换成功",
		Data:    result.Data,
	})
	for _, filename := range filenames {
		err = os.Remove(filename)
		if err != nil {
			log.Println("删除文件失败")
			// 重试
		}
	}
	return
}
